package com.neusoft.ch8;

import java.io.FileInputStream;
import java.io.FileNotFoundException;

/*
 * 课堂笔记：
 *    异常：非正常运行的程序出现的情况就是异常；
 *    异常分类：
 *       共同的父类：Throwable
 *       错误：Error
 *       异常：Exception
 *   异常根据出现的时机分为：
 *      检查性异常：出现在编译期；【又叫：非运行时异常/编译时异常】
 *         检查性因为出现在编译器，如果有异常需要进行处理，则必须使用异常处理机制处理之后，才能编译通过，
 *         否则会出现编译错误。
 *         检查性异常（非运行时异常）需要进行显式的异常处理机制进行处理；
 *      
 *      非检查性异常：出现在运行期；【又叫：运行时异常】
 *         非检查异常在编译时不会发现有异常，只有在运行时才会出现异常；
 *         【编译期不需要进行显式异常处理，编译就能通过，但是运行时，可能会发生异常】
 *          包括运行时异常（RuntimeException与其子类）和错误（Error），这些异常不需要进行显式的异常处理；
 *          数组越界，空指针异常；
 *          非检查型异常一般是由程序逻辑错误引起的，应该从逻辑严密角度尽可能避免这类异常的发生；
 *    
 *    异常处理机制：【主要是针对检查性异常进行处理】
 *      第一种：
 *           try-catch-finally
 *           语法：
 *              try{
 *                 可能出现异常的代码块；
 *              }catch(截获的异常的类型  实例变量名){
 *              	当前截获的异常的处理；
 *              }catch(截获的异常的类型N 实例变量名n){
 *              	当前截获的异常的处理；
 *              }finally{
 *              	异常处理的收尾工作；              
 *              }
 *           执行流程：
 *              先执行try中的语句块，当执行过程中发生了异常，则转入catch部分处理；
 *              catch处理完之后，如果有finally则执行该部分，如果没有则异常处理结束；   
 *           解析：
 *               try中放的是可能出现错误的代码块；
 *               catch中的 截获的异常的类型 一般是Throwable的（重点是对Exception的处理）的子类
 *               finally语句块无论是否发生异常都会被执行；
 *               如果有多个catch，则从前往后捕获的异常的范围应该是从小到大（从子类到父类），最上层的父类是Exception；
 *               也就是说，Exception类可以捕获所有的异常；
 *      第二种：
 *          throws处理方式。
 *          在方法声明之后使用throws将该方法中可能发生的异常抛给上层调用者进行处理；
 *          如果一直向上抛，最终由jvm来进行处理；
 *          throws关键字后面，可以跟多个异常，中间用逗号分割;
 *                    
 *    异常机制作用：
 *       在程序发生异常的情况下，保证程序还能正常执行； 
 *       非检查性异常也可以使用异常处理机制进行处理；
 *    
 *    throw关键字用法：
 *       可以通过 throw人为抛出一个异常；然后再按照异常处理机制进行处理；
 *       语法：
 *          throw new 抛出的异常类(); 
 *       throw人为抛出的异常，根据抛出异常的类型决定是否需要进行显式的异常处理机制；  
 *       
 *   自定义异常：
 *      通过自定义的异常类继承Exception或其子类通过多态的方式进行实现；
 *                    
 */
public class TestCh8 {

	//public static void main(String[] args) throws FileNotFoundException{
	public static void main(String[] args) {
		test02();
		System.out.println("=======================");
		try {
			test04();
		} catch (IllegalAgeException e1) {
			e1.printStackTrace();
		}
		System.out.println("=======================");
		try {
			test03();
		} catch (Exception e) {
			System.out.println("发生异常：" + e.getMessage());
			// e.printStackTrace();
		}
		System.out.println("在异常处理机制的保护下，发生异常时可以保证程序得于继续执行。。。");
	}

	private  static void test04() throws IllegalAgeException {
		int age = 1000;
		if(age > 300) {
			//throw new IllegalArgumentException("年龄参数非法"); // 如果抛出非检查性异常，则不需要显式处理
			//throw new IllegalAccessException("年龄非法访问异常"); // 检查性异常，需要显式异常处理
			// 抛出自定义异常类
			throw new IllegalAgeException("年龄范围异常");
		}
	}
	
	/**
	 * 非检查性异常：运行时期发现异常错误 数组越界、空指针、除数为0
	 */
	private static void test01() {
		
		int i = 0;
		int j = 10 / i;
		System.out.println("j=" + j);
		
		
		System.out.println("程序执行完成。");

	}
	/**
	 * 非检查性异常：运行时期发现异常错误 数组越界、空指针、除数为0
	 * 也可以使用异常处理机制进行处理，保证主干程序的正常执行
	 */
	private static void test011() {
		try {
			
		int i = 0;
		int j = 10 / i;
		System.out.println("j=" + j);
		}catch(Exception e) {
			System.out.println("发生了异常，但是有了异常处理机制，主体程序还可以正常运行：");
			System.out.println("异常原因："+e.getMessage());
		}
		
		
		System.out.println("程序执行完成。");

	}
	/**
	 * 检查性异常：运行时期发现异常错误【编译期也就是写代码时必须进行显式的异常处理，才可以正常编译通过】 文件未找到
	 */
	private static void test02() {
		try {
			// 文件输入流，会引发文件无法找到异常
			FileInputStream fis = new FileInputStream("D:\\temp\\jvm\\Hello.java");
			// return;
		} catch (FileNotFoundException e) {
			System.out.println("发生异常：" + e.getMessage());
			e.printStackTrace();
			return;
		} catch (Exception e) {
			System.out.println("发生异常：" + e.getMessage());
			e.printStackTrace();
		}finally {
			// 收尾处理：无论是否发生异常，都会被执行
			System.out.println("执行了，finally语句块");
		}
		
	}
	/**
	 * 检查性异常：运行时期发现异常错误【编译期也就是写代码时必须进行显式的异常处理，才可以正常编译通过】 文件未找到
	 */
	private static void test021() {
		try {
			// 文件输入流，会引发文件无法找到异常
			FileInputStream fis = new FileInputStream("D:\\temp\\jvm\\Hello2.java");
			// 会引起类无法找到异常
			Class.forName("");
		/**
		 * 性特性：要求 | 前后的异常类型不能相互有父子类的包含关系；	
		 */
		} catch (FileNotFoundException|ClassNotFoundException e) {
			System.out.println("发生异常：" + e.getMessage());
			e.printStackTrace();
		} finally {
			// 收尾处理：无论是否发生异常，都会被执行
			System.out.println("执行了，finally语句块");
		}
	}
	
	/**
	 * 异常处理机制：throws处理方式
	 * @throws FileNotFoundException 抛出的异常
	 */
	private static void test03() throws FileNotFoundException {
		// 文件输入流，会引发文件无法找到异常
		FileInputStream fis = new FileInputStream("D:\\temp\\jvm\\Hello2.java");
	}
}
